"""
重写ModelViewSet的部分方法，为响应数据添加'code'、'msg'两个字段，方便前端程序做相应处理。
"""
from django.utils.timezone import now

from rest_framework import viewsets
from rest_framework import status
from rest_framework.response import Response
from django.contrib.auth.models import User

class MyModelViewSet(viewsets.ModelViewSet):
    def create(self, request, *args, **kwargs):
        """
        创建一个模型的实例.
        """
        # 直接修改request.data,使用API提交时会报 AttributeError: This QueryDict instance is immutable错误
        # request.data['createdBy'] = request.user.username
        # request.data['createdDate'] = now()
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.validated_data['createdBy'] = request.user.username
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        context = {
            'code': status.HTTP_201_CREATED,
            'msg': '创建成功！',
            'data': serializer.data
        }
        # czj第一个修改点
        user = self.request.user
        obj = serializer.instance

        return Response(context, status=status.HTTP_201_CREATED, headers=headers)

    def retrieve(self, request, *args, **kwargs):
        """
        检索一个模型的实例.
        """
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        context = {
            'code': status.HTTP_200_OK,
            'msg': '检索成功！',
            'data': serializer.data
        }
        return Response(context)

    def update(self, request, *args, **kwargs):
        """
        更新一个模型的实例.
        """
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        # czj第二个修改点
        names = getname(instance)  # 1.获得所有属性名
        old_box = getnum(instance, names)  # 2.获取旧值

        # 直接修改request.data,使用API提交时会报 AttributeError: This QueryDict instance is immutable错误
        # 为请求数据添加操作者和操作时间
        # request.data['lastEditedBy'] = request.user.username
        # request.data['lastEditedDate'] = now()

        serializer = self.get_serializer(
            instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        serializer.validated_data['lastEditedBy'] = request.user.username
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        context = {
            'code': status.HTTP_200_OK,
            'msg': '更新成功！',
            'data': serializer.data
        }
        # czj第三个修改点
        newbox = getnum(instance, names)  # 获取新值

        # czj第四个修改点 新增操作记录实例并新增历史记录外键
        user = self.request.user
        obj = serializer.instance
        # differ(old_box, newbox)

        return Response(context)

    def destroy(self, request, *args, **kwargs):
        """
        销毁模型实例.
        """
        instance = self.get_object()

        # 永久删除
        # self.perform_destroy(instance)

        # 临时删除
        instance.deleted = 1
        instance.save()
        context = {
            'code': status.HTTP_204_NO_CONTENT,
            'msg': '删除成功！',
            'data': ''
        }
        # czj第五个修改点
        user = self.request.user
        obj = instance
        # 如果反馈“HTTP_204_NO_CONTENT”，会导致context中内容没有返回给浏览器
        return Response(context, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        """
        列出查询集.
        """
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            context = {
                'code': status.HTTP_200_OK,
                'msg': '查询成功！',
                'data': serializer.data
            }
            return self.get_paginated_response(context)

        serializer = self.get_serializer(queryset, many=True)
        context = {
            'code': status.HTTP_200_OK,
            'msg': '查询成功！',
            'data': serializer.data
        }
        return Response(context)


# czj封装函数
# 获取属性名和别名
def getname(instance):
    obj_names = {}
    names = instance._meta.fields
    for obj in names:
        obj_names[str(obj.name)] = str(obj.verbose_name)
    return obj_names
# 获取属性值
def getnum(instance, names):
    box = {}
    for name, vname in names.items():
        if name != 'lastEditedDate':
            if name == 'createdBy' or name == 'lastEditedBy' or name == 'assignedTo' or name == 'responsibility' or name == 'executive' or name == 'lastOne':
                user = User.objects.filter(username=getattr(instance, name)).first()
                if user:
                    box[vname] = user.extension.realname
                else:
                    box[vname] = getattr(instance, name)
            elif name == 'status' or name == 'finishedType' or name == 'isExemption' or name == 'isDoublePunish' or name == 'penalty':
                switcher = {
                    'unconfirmed': '待确认',
                    'wait': '待处理',
                    'finished': '已处理',
                    'closed': '已关闭',
                    'repeat': '转交',
                    'disagree': '不予采纳',
                    1: '是',
                    0: '否',
                    None: '',
                }
                box[vname] = switcher.get(getattr(instance, name), getattr(instance, name))
            else:
                box[vname] = getattr(instance, name)
    return box
# 判断两个字典的差异新增历史记录


# def differ(old_box, newbox, newAction):
#     new_history_items = []
#     for a in newbox:
#         if a in old_box:
#             if newbox[a] != old_box[a]:
#                 newhistory = History(action=newAction, field=a, old=old_box[a] if old_box[a] else '', new=newbox[a], diff='<b>'+str(
#                     a)+'：由</b> 【'+str(old_box[a]).replace('<p>','').replace('</p>','')+'】<b>修改为</b>【'+str(newbox[a]).replace('<p>','').replace('</p>','')+'】')
#                 newhistory.save()
#                 new_history_items.append(newhistory.id)
#     return new_history_items
